﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using Algoritmia.DataStructures.Collections;

namespace Demos.Collections
{
    class ViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        LinkedListCollection<int> _listaEnlazada = new LinkedListCollection<int>();
        ListCollection<int> _lista = new ListCollection<int>();

        public ObservableCollection<ElementoVisual> ContenidoLista { get; set; }
        public ObservableCollection<ElementoVisual> ContenidoListaEnlazada { get; set; }

        private string _elementoAAñadir;
        public string ElementoAAñadir
        {
            get { return _elementoAAñadir; }
            set
            {
                _elementoAAñadir = value;
                NotifyPropertyChanged("ElementoAAñadir");
            }
        }

        private string _elementoAEliminar;
        public string ElementoAEliminar
        {
            get { return _elementoAEliminar; }
            set
            {
                _elementoAEliminar = value;
                NotifyPropertyChanged("ElementoAEliminar");
            }
        }

        private string _elementoABuscar;
        public string ElementoABuscar
        {
            get { return _elementoABuscar; }
            set
            {
                _elementoABuscar = value;
                NotifyPropertyChanged("ElementoABuscar");
            }
        }

        private Brush _resultadoBusqueda;
        public Brush ResultadoBusqueda
        {
            get { return _resultadoBusqueda; }
            set
            {
                _resultadoBusqueda = value;
                NotifyPropertyChanged("ResultadoBusqueda");
            }
        }

        public string ContadorLista
        {
            get { return _lista.Count.ToString(); }
        }

        public string ContadorListaEnlazada
        {
            get { return _listaEnlazada.Count.ToString(); }
        }

        private bool[] _seleccionColeccion;
        public bool[] SeleccionColeccion
        {
            get { return _seleccionColeccion; }
            set
            {
                _seleccionColeccion = value;
                NotifyPropertyChanged("SeleccionColeccion");
            }
        }

        private int _indiceListaSeleccionado;
        public int IndiceListaSeleccionado
        {
            get { return _indiceListaSeleccionado; }
            set
            {
                _indiceListaSeleccionado = value;
                NotifyPropertyChanged("IndiceListaSeleccionado");
                if (value > 0 && value < _lista.Count)
                {
                    ElementoAEliminar = _lista.ElementAt(value).ToString();
                }
            }
        }

        private int _indiceListaEnlazadaSeleccionado;
        public int IndiceListaEnlazadaSeleccionado
        {
            get { return _indiceListaEnlazadaSeleccionado; }
            set
            {
                _indiceListaEnlazadaSeleccionado = value;
                NotifyPropertyChanged("IndiceListaEnlazadaSeleccionado");
                if (value % 2 == 0 && value > 0 && value < ContenidoListaEnlazada.Count)
                {
                    ElementoAEliminar = _listaEnlazada.ElementAt(value / 2).ToString();
                }
            }
        }

        public ICommand AñadirCommand { get; private set; }
        public ICommand GenerarAlAzarCommand { get; private set; }
        public ICommand EliminarCommand { get; private set; }
        public ICommand BorrarTodoCommand { get; private set; }
        public ICommand BuscarCommand { get; private set; }


        public ViewModel()
        {
            SeleccionColeccion = new bool[3];
            SeleccionColeccion[0] = true;

            ContenidoLista = new ObservableCollection<ElementoVisual>();
            ContenidoListaEnlazada = new ObservableCollection<ElementoVisual>();

            AñadirCommand = new RelayCommand(Añadir, () => !string.IsNullOrEmpty(ElementoAAñadir));
            GenerarAlAzarCommand = new RelayCommand(GenerarAlAzar, () => true);
            EliminarCommand = new RelayCommand(Eliminar, () => !string.IsNullOrEmpty(ElementoAEliminar));
            BorrarTodoCommand = new RelayCommand(BorrarTodo, () => _lista.Count > 0 || _listaEnlazada.Count > 0);
            BuscarCommand = new RelayCommand(Buscar, () => !string.IsNullOrEmpty(ElementoABuscar));
        }


        private void Buscar()
        {
            try
            {
                if (SeleccionColeccion[0])
                {
                    ResultadoBusqueda = _lista.Contains(int.Parse(ElementoABuscar)) ? Brushes.Green : Brushes.Red;
                }
                else if (SeleccionColeccion[1])
                {
                    ResultadoBusqueda = _listaEnlazada.Contains(int.Parse(ElementoABuscar)) ? Brushes.Green : Brushes.Red;
                }
                else if (SeleccionColeccion[2])
                {
                    ResultadoBusqueda = _listaEnlazada.Contains(int.Parse(ElementoABuscar))
                                        && _lista.Contains(int.Parse(ElementoABuscar)) ? Brushes.Green : Brushes.Red;
                }
            }
            catch (FormatException)
            {
                MessageBox.Show("Formato incorrecto", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void BorrarTodo()
        {
            _lista = new ListCollection<int>();
            _listaEnlazada = new LinkedListCollection<int>();
            ContenidoLista = new ObservableCollection<ElementoVisual>();
            ContenidoListaEnlazada = new ObservableCollection<ElementoVisual>();
            NotifyPropertyChanged("ContadorLista");
            NotifyPropertyChanged("ContadorListaEnlazada");
            NotifyPropertyChanged("ContenidoLista");
            NotifyPropertyChanged("ContenidoListaEnlazada");
        }

        private void Eliminar()
        {
            try
            {
                if (SeleccionColeccion[0])
                {
                    EliminarDeLista();
                }
                else if (SeleccionColeccion[1])
                {
                    EliminarDeListaEnlazada();
                }
                else if (SeleccionColeccion[2])
                {
                    EliminarDeLista();
                    EliminarDeListaEnlazada();
                }
                NotifyPropertyChanged("ContadorLista");
                NotifyPropertyChanged("ContadorListaEnlazada");
                NotifyPropertyChanged("ContenidoLista");
                NotifyPropertyChanged("ContenidoListaEnlazada");
            }
            catch (FormatException)
            {
                MessageBox.Show("Formato incorrecto", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void EliminarDeLista()
        {
            _lista.Remove(int.Parse(ElementoAEliminar));
            ContenidoLista = new ObservableCollection<ElementoVisual>();
            foreach (var i in _lista)
            {
                ContenidoLista.Add(new Caja(30, 30, i.ToString()));
            }
        }

        private void EliminarDeListaEnlazada()
        {
            _listaEnlazada.Remove(int.Parse(ElementoAEliminar));
            ContenidoListaEnlazada = new ObservableCollection<ElementoVisual>();
            for (var i = 0; i < _listaEnlazada.Count; i++)
            {
                if (i != 0)
                {
                    ContenidoListaEnlazada.Add(new Flecha(0, 0, 15, 0));
                }
                ContenidoListaEnlazada.Add(new Caja(30, 30, _listaEnlazada.ElementAt(i).ToString()));
            }
        }

        private void GenerarAlAzar()
        {
            var r = new Random(DateTime.Now.Millisecond);
            for (var i = 0; i < 10; i++)
            {
                ElementoAAñadir = r.Next(0, 100).ToString();
                Añadir();
            }
        }

        private void Añadir()
        {
            try
            {
                if (SeleccionColeccion[0])
                {
                    AñadirALista();
                }
                else if (SeleccionColeccion[1])
                {
                    AñadirAListaEnlazada();
                }
                else if (SeleccionColeccion[2])
                {
                    AñadirALista();
                    AñadirAListaEnlazada();
                }
            }
            catch (FormatException)
            {
                MessageBox.Show("Formato incorrecto", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void AñadirALista()
        {
            _lista.Add(int.Parse(ElementoAAñadir));
            ContenidoLista.Add(new Caja(30, 30, ElementoAAñadir));
            NotifyPropertyChanged("ContadorLista");
        }

        private void AñadirAListaEnlazada()
        {
            if (_listaEnlazada.Count > 0)
            {
                ContenidoListaEnlazada.Add(new Flecha(0, 0, 15, 0));

            }
            _listaEnlazada.Add(int.Parse(ElementoAAñadir));
            ContenidoListaEnlazada.Add(new Caja(30, 30, ElementoAAñadir));
            NotifyPropertyChanged("ContadorListaEnlazada");
        }
    }
}
